﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using KamLib.Web.MVC;


namespace KamLib.Web.Bootstrap
{

    public enum ButtonSize { Normal, Mini, Small, Large }
    public enum ButtonKind { Normal, Danger, Inverse, Primary, Success, Warning }


    public class Button : DropDown
    {

        public ButtonKind Kind;
        public ButtonSize Size;

        public delegate Button Setter(Action<Link.Setter> title = null, Action<DropDownMenu.Setter> menu = null, ButtonSize size = ButtonSize.Normal);

        public Button Set(Action<Link.Setter> title = null, Action<DropDownMenu.Setter> menu = null, ButtonSize size = ButtonSize.Normal)
        {
            Title = title;
            Menu = menu;
            Size = size;
            return this;
        }

        public static implicit operator Button(Action<Setter> setterAction)
        {
            var el = new Button();
            if (setterAction == null) return el;

            Setter setter = el.Set;
            setterAction(setter);
            return el;
        }

    }


    public static partial class ButtonHelper
    {

        #region Size

        public static T Size<T>(this T me, ButtonSize size)
            where T : Button
        {
            me.Size = size;
            return me;
        }

        public static T Mini<T>(this T me)
            where T : Button
        {
            me.Size = ButtonSize.Mini;
            return me;
        }

        public static T Small<T>(this T me)
            where T : Button
        {
            me.Size = ButtonSize.Small;
            return me;
        }

        public static T Large<T>(this T me)
            where T : Button
        {
            me.Size = ButtonSize.Large;
            return me;
        }

        #endregion


        #region Kind

        public static T Kind<T>(this T me, ButtonKind value)
            where T : Button
        {
            me.Kind = value;
            return me;
        }

        public static T Danger<T>(this T me)
            where T : Button
        {
            me.Kind = ButtonKind.Danger;
            return me;
        }

        public static T Inverse<T>(this T me)
            where T : Button
        {
            me.Kind = ButtonKind.Inverse;
            return me;
        }

        public static T Primary<T>(this T me)
            where T : Button
        {
            me.Kind = ButtonKind.Primary;
            return me;
        }

        public static T Success<T>(this T me)
            where T : Button
        {
            me.Kind = ButtonKind.Success;
            return me;
        }

        public static T Warning<T>(this T me)
            where T : Button
        {
            me.Kind = ButtonKind.Warning;
            return me;
        }

        #endregion
        
    }


    partial class BootstrapHelper
    {

        #region For MVC

        public Button Button(Action<Button.Setter> setter)
        {
            return Button((Button)setter);
        }

        public Button Button(MvcText title, params Action<DropDownItem.Setter>[] itemSetters)
        {
            return Button(new Button
            {
                Title = new Link { Text = title, },
                Menu = new DropDownMenu().Items(itemSetters),
            });
        }

        public Button Button(MvcText title, string click, params Action<DropDownItem.Setter>[] itemSetters)
        {
            return Button(new Button
            {
                Title = new Link { Text = title, Url = click },
                Menu = new DropDownMenu().Items(itemSetters),
            });
        }

        #endregion


        #region Renders

        [Browsable(false)]
        public virtual string GetAddClass(Button el)
        {
            var kind = el.Kind != ButtonKind.Normal ? "btn-" + el.Kind.ToString().ToLowerInvariant() : null;
            var size = el.Size != ButtonSize.Normal ? "btn-" + el.Size.ToString().ToLowerInvariant() : null;

            var s = kind;
            if (size != null)
                s = s != null ? s + " " + size : size;

            return s;
        }

        [Browsable(false)]
        public virtual bool HasHandler(Button el)
        {
            return el != null && el.Title != null && el.Title.Url.yes();
        }

        [Browsable(false)]
        public virtual Button Handler(Button el, MvcElement dest = null)
        {
            (dest ?? el).Attrs(@"onclick=""" + el.Title.Url + @"""");
            return el;
        }

        [Browsable(false)]
        public virtual Button Button(Button el)
        {
            if (!el.Title.yes()) return el;

            if (!el.HasMenu)
            {
                el.Tag("button").Class("btn");
                el.PreRenderer = () => el.Class(GetAddClass(el));

                if (HasHandler(el))
                    Handler(el);
                el.Renderer = el.Title.Render;
            }
            else if (HasHandler(el))
            {
                el.TagIf("div").Class("btn-group");
                el.Title.TagIf("button").Class("btn");
                Handler(el, el.Title);
                DropDownMenu(el.Menu);

                el.PreRenderer = () => el.Title.Class(GetAddClass(el));
                el.Renderer = sb =>
                {
                    var addClass = GetAddClass(el);
                    el.Title.Render(sb);
                    sb.Append(@"<button class=""btn dropdown-toggle");
                    if (addClass != null)
                    {
                        sb.Append(' ');
                        sb.Append(addClass);
                    }
                    sb.Append(@""" data-toggle=""dropdown""><span class=""caret""></span></button>");
                    el.Menu.Render(sb);
                };
            }
            else
            {
                el.TagIf("div").Class("btn-group");
                el.Title.TagIf("a").Class("btn dropdown-toggle").Attrs(@"data-toggle=""dropdown"" href=""#""");
                el.Title.Text += @" <span class=""caret""></span>";
                DropDownMenu(el.Menu);

                var el_ = el;
                el.PreRenderer = () => el.Title.Class(GetAddClass(el));
                el.Renderer = sb =>
                {
                    el_.Title.Render(sb);
                    el_.Menu.Render(sb);
                };
            }

            return el;
        }

        #endregion

    }


}
